package com.sean.iphoneAppWorkspace;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.Scroller;

/**
 * 滑动控件 暫且將一滑動一屏幕看做一頁
 * 
 * @author Sean
 * 
 */
public class Workspace extends ViewGroup {
	protected static final String TAG = "Workspace";
	protected static final int INVALID_SCREEN = -1;
	protected final static int TOUCH_STATE_REST = 0;
	protected final static int TOUCH_STATE_SCROLLING = 1;
	protected final static int TOUCH_STATE_SCROLL_ANI = 2;
	protected final static int TOUCH_STATE_FLING = 3;
	protected GestureDetector mGestureDetector;
	protected ScrollScreenListener mScrollScreenListener;
	protected ScreenChangeListener mScreenChangeListener;
	protected int mCurrentScreen = 0;
	protected int mNextScreen = 0;
	protected int mLastScreen = 0;
	protected int cutPosition = 0;
	protected int lastPosition = 0;
	protected Scroller mScroller;
	protected int mTouchState = TOUCH_STATE_REST;
	protected float mDownMotionX;
	protected float mDownMotionY;
	protected boolean mLocked;
	protected int mAnimationTime = 1000;
	protected boolean isShowPositionBar = true;

	protected PositionBar mPositionBar;

	public Workspace(Context context) {
		super(context);
		init();
	}

	public Workspace(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
		initFromAttributes(context, attrs);

	}

	public Workspace(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
		initFromAttributes(context, attrs);
	}

	protected void initFromAttributes(Context context, AttributeSet attrs) {
	}

	/**
	 * 初始化
	 */
	public void init() {
		mScreenChangeListener = new ScreenChangeListener() {
			@Override
			public void onScreenChangeListener(int currentScreen,
					int lastenScreen) {
				// Toast.makeText(getContext(), "" + currentScreen,
				// Toast.LENGTH_SHORT).show();
			}
		};
		mGestureDetector = new GestureDetector(new MGestureDetectorListener());
		mScroller = new Scroller(getContext());
		this.setLongClickable(true);
	}

	/**
	 * 设置宽度高度的局限
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		final int width = MeasureSpec.getSize(widthMeasureSpec);
		final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		if (widthMode != MeasureSpec.EXACTLY) {
			throw new IllegalStateException(
					"Workspace can only be used in EXACTLY mode.");
		}
		final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		if (heightMode != MeasureSpec.EXACTLY) {
			throw new IllegalStateException(
					"Workspace can only be used in EXACTLY mode.");
		}
		// 给孩子添加确切宽度高度
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
			getChildAt(i).setLongClickable(true);
		}
		refurbishScreen();
	}

	/**
	 * 添加进来的子vie擺放位置
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int childLeft = 0;
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() != View.GONE) {
				final int childWidth = child.getMeasuredWidth();
				child.layout(childLeft, 0, childLeft + childWidth,
						child.getMeasuredHeight());
				childLeft += childWidth;
			}
		}
	}

	/**
	 * 从而被系统重新绘制，所以它的 dispatchDraw 函数会被调用来进行子 View（ImageView）的绘制
	 * 这个绘的函数很重要，是制作立方体翻页等特效的关键地方
	 * 
	 * @param canvas
	 */
	@Override
	protected void dispatchDraw(Canvas canvas) {
		final long drawingTime = getDrawingTime();
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			drawChild(canvas, getChildAt(i), drawingTime);
		}
	}

	/**
	 * 拦截滑动事件
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// Log.e("onInterceptTouchEvent", "onInterceptTouchEvent");
		final int action = ev.getAction();
		final float x = ev.getX();
		final float y = ev.getY();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			mDownMotionX = x;
			mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST
					: TOUCH_STATE_SCROLLING;
			lastPosition = cutPosition;
			mLastScreen = mCurrentScreen;
			break;
		case MotionEvent.ACTION_MOVE:
			if (mPositionBar != null && isShowPositionBar == true)
				mPositionBar.show();
			Log.e("onInterceptTouchEvent", "ACTION_MOVE");
			return true;
		case MotionEvent.ACTION_CANCEL:
			Log.e("onInterceptTouchEvent", "ACTION_CANCEL");
		case MotionEvent.ACTION_UP:

			if (mTouchState != TOUCH_STATE_REST)
				scrollScreen();
		}
		return mTouchState != TOUCH_STATE_REST;

	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		final int action = ev.getAction();
		final float x = ev.getX();
		if (mGestureDetector != null) {
			mGestureDetector.onTouchEvent(ev);
		}
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			if (!mScroller.isFinished()) {
				mScroller.abortAnimation();
			}
			if (mPositionBar != null && isShowPositionBar == true)
				mPositionBar.show();
			mDownMotionX = ev.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			if (mPositionBar != null && isShowPositionBar == true)
				mPositionBar.show();
			mTouchState = TOUCH_STATE_SCROLLING;
			cutPosition = (int) (lastPosition + (mDownMotionX - ev.getX()));
			cutPosition = Math.max(
					Math.min(cutPosition, (getChildCount() - 1)
							* getMeasuredWidth() + 10), -10);

			// 如果滑动过了屏幕促发屏幕改变事件
			mNextScreen = calculateNextScreen(cutPosition);
			if (mCurrentScreen != mNextScreen) {
				if (mScreenChangeListener != null)
					mScreenChangeListener.onScreenChangeListener(mNextScreen,
							mCurrentScreen);
				mCurrentScreen = mNextScreen;
			}
			scrollTo(cutPosition, 0);
			break;
		case MotionEvent.ACTION_UP:// 计算nextPosition位置
			 Log.e("onTouchEvent", "UPUPUPUPUP");
			switch (mTouchState) {
			case TOUCH_STATE_SCROLLING:
				// mNextScreen = calculateNextScreen(cutPosition);
			case TOUCH_STATE_FLING:
			default:
				if (mTouchState != TOUCH_STATE_REST)
					scrollScreen();
			}
			break;
		}
		return true;
	}

	/**
	 * 得知cutPosition跟mNextScreen 使屏幕 滚动到目標
	 */
	public void scrollScreen() {
		if (mPositionBar != null && isShowPositionBar == true)
			mPositionBar.show();
		if (mScrollScreenListener != null)
			mScrollScreenListener.onStartScrollScreen(mCurrentScreen);
		final int nextPosition = mNextScreen * getMeasuredWidth();
		int time = Math.abs((int) (nextPosition - cutPosition))
				* mAnimationTime / getMeasuredWidth();
		mScroller.startScroll(cutPosition, 0, nextPosition - cutPosition, 0,
				time);
		mTouchState = TOUCH_STATE_SCROLL_ANI;
		mCurrentScreen = mNextScreen;
		computeScroll();
	}

	/**
	 * /** 通过当前位置计算出属于哪个屏幕
	 * 
	 * @param cutPt当前位置cutPosition
	 * @return newScreen计算后属于哪个屏幕
	 */
	protected int calculateNextScreen(int cutPt) {
		int nextScreen = cutPt / getMeasuredWidth();
		if (cutPt - (getMeasuredWidth() * nextScreen) >= getMeasuredWidth() / 2)
			nextScreen++;
		return nextScreen = Math.min(Math.max(0, nextScreen),
				getChildCount() - 1);

	}

	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()
				&& mTouchState == TOUCH_STATE_SCROLL_ANI) {
			cutPosition = mScroller.getCurrX();
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();
		} else if (mTouchState == TOUCH_STATE_SCROLL_ANI) {
			// 若动画结束
			mTouchState = TOUCH_STATE_REST;
			cutPosition = mCurrentScreen * getMeasuredWidth();
			if (mScrollScreenListener != null)
				mScrollScreenListener.onEndScrollScreen(mCurrentScreen);
			lastPosition = cutPosition;
		}
	}

	/**
	 * 滑动事件 处理器
	 * 
	 * @author Administrator
	 * 
	 */
	class MGestureDetectorListener extends SimpleOnGestureListener {
		@Override
		public boolean onDown(MotionEvent e) {
			return false;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			Log.e("onFling", "onFling");
			mTouchState = TOUCH_STATE_FLING;
			if (velocityX > 0) {
				mNextScreen = Math.max(mLastScreen - 1, 0);
			} else {// 往前翻
				mNextScreen = Math.min(mLastScreen + 1, getChildCount() - 1);
			}
			if (mScreenChangeListener != null)
				mScreenChangeListener.onScreenChangeListener(mNextScreen,
						mCurrentScreen);
			mCurrentScreen = mNextScreen;

			return false;
		}

		@Override
		public void onLongPress(MotionEvent e) {
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			return false;
		}

		@Override
		public void onShowPress(MotionEvent e) {
		}

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			return false;
		}
	}

	public void scrollLeft() {
		cutPosition = mCurrentScreen * getMeasuredWidth();
		mNextScreen = Math.max(mCurrentScreen - 1, 0);
		if (mScreenChangeListener != null)
			mScreenChangeListener.onScreenChangeListener(mNextScreen,
					mCurrentScreen);
		mCurrentScreen = mNextScreen;
		scrollScreen();
	}

	public void scrollRight() {
		cutPosition = mCurrentScreen * getMeasuredWidth();
		mNextScreen = Math.min(getChildCount() - 1, mCurrentScreen + 1);
		if (mScreenChangeListener != null)
			mScreenChangeListener.onScreenChangeListener(mNextScreen,
					mCurrentScreen);
		mCurrentScreen = mNextScreen;
		scrollScreen();

	}

	/**
	 * 设置当前页面
	 * 
	 * @param defaultScreen
	 */
	public void setCurrentScreen(int defaultScreen) {
		mCurrentScreen = defaultScreen;
		// if (mPositionBar != null && isShowPositionBar == true)
		// mPositionBar.show();
		cutPosition = mCurrentScreen * getMeasuredWidth();
		scrollTo(mCurrentScreen * getMeasuredWidth(), 0);
	}

	/**
	 * 宽度改变后刷新页面
	 */
	public void refurbishScreen() {
		Log.e("getMeasuredWidth", "" + getMeasuredWidth());
		scrollTo(mCurrentScreen * getMeasuredWidth(), 0);
	}

	public boolean isShowPositionBar() {
		return isShowPositionBar;
	}

	public void setShowPositionBar(boolean isShowPositionBar) {
		this.isShowPositionBar = isShowPositionBar;
	}

	/**
	 * 获取当前页
	 * 
	 * @return
	 */
	public int getCurrentScreen() {
		return mCurrentScreen;
	}

	public void showPositionBar() {
	}

	/**
	 * 设置监听器、完整滚动完一页后触发
	 * 
	 * @param chieveScreenListener
	 *            内置监听器
	 */
	public void setScrollScreenListener(
			ScrollScreenListener scrollScreenListener) {
		mScrollScreenListener = scrollScreenListener;
	}

	// public void set
	public interface ScreenChangeListener {
		public void onScreenChangeListener(int nextScreen, int currenScreen);
	}

	public interface ScrollScreenListener {
		public void onEndScrollScreen(int currentScreen);

		public void onStartScrollScreen(int currentScreen);
	}

	public PositionBar createPositionBar() {
		if (mPositionBar == null)
			mPositionBar = new PositionBar(this.getContext());
		return mPositionBar;
	}

	/**
	 * 显示页数辅助工具条 每一个workspace只对应一个这个类 该类对象游workspace对象的createPositionBar方法取得实例
	 * 该类的方法show显示
	 * 
	 * @author Administrator
	 * 
	 */
	public class PositionBar extends View {
		private final static int LEGNTH = 26;
		final static String TAG = "PositionBar";
		private Paint mPaint;
		// private Bitmap curBitmap;
		// private Bitmap otherBitmap;
		private Animation animation;

		private PositionBar(Context context) {
			super(context);
			init();

		}

		private PositionBar(Context context, AttributeSet attrs) {
			super(context, attrs);
			init();

		}

		private PositionBar(Context context, AttributeSet attrs, int defStyle) {
			super(context, attrs, defStyle);
			init();
		}

		private void init() {
			this.setVisibility(View.INVISIBLE);
			// curBitmap = DrawableTool.drawableToBitmap(getContext()
			// .getResources().getDrawable(
			// R.drawable.workspace_position_cur));
			// otherBitmap = DrawableTool.drawableToBitmap(getContext()
			// .getResources().getDrawable(
			// R.drawable.workspace_position_other));
			animation = new AlphaAnimation(1, 0);
			animation.setStartOffset(1500);
			animation.setDuration(1000);
			mPaint = new Paint();
			mPaint.setColor(Color.WHITE);
			mPaint.setAlpha(200);
			mPaint.setAntiAlias(true);
			mPaint.setFilterBitmap(true);

		}

		@Override
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			setMeasuredDimension(Workspace.this.getChildCount() * LEGNTH,
					LEGNTH);
			// Log.e("onMeasure", "onMeasure" + ApiDemos.i);
		}

		@Override
		public void onDraw(Canvas canvas) {
			// Log.e(TAG, "onDraw");
			for (int i = 0; i < Workspace.this.getChildCount(); i++) {
				if (i == Workspace.this.mCurrentScreen) {
					canvas.drawCircle(LEGNTH / 2 + i * LEGNTH, LEGNTH / 2, 6,
							mPaint);
					// canvas.drawBitmap(curBitmap, curBitmap.getWidth() * i, 0,
					// mPaint);
				} else {
					canvas.drawCircle(LEGNTH / 2 + i * LEGNTH, LEGNTH / 2, 3,
							mPaint);
					// canvas.drawBitmap(otherBitmap, otherBitmap.getWidth() *
					// i,
					// 0, mPaint);
				}
			}
		}

		public void show() {
			// this.setVisibility(VISIBLE);
			this.startAnimation(animation);
		}

	}
}
